<?php
/**
 * 전역 Abstract 클래스들을 관리합니다.
 * 현재는 해당 파일에 모아두도록 하며,
 * 클래스 사이즈가 커지면 따로 구조를 잡는 방안으로 합니다.
 *
 * @package boot
 * @author  Platform Team
 */


/**
 * --------------------------------------------
 * 싱글톤 관리 클래스
 * --------------------------------------------
 *
 * @deprecated
 */
abstract class Singleton
{
    /**
     * 인스턴스 관리 배열
     */
    protected static $aInstance = array();

    /**
     * 생성자
     */
    protected function __construct(){}

    /**
     * singleton
     *
     * @return object
     */
    public static function getInstance($sClass)
    {
        if (!self::$aInstance[$sClass]) self::$aInstance[$sClass] = new $sClass;

        return self::$aInstance[$sClass];
    }

    /**
     * instance destruct
     */
    public static function instancedel($sClass)
    {
        self::$aInstance[$sClass] = false;
    }
}

/**
 * --------------------------------------------
 * 컨트롤러 최상위 추상화 클래스
 * --------------------------------------------
 */
abstract class Controller
{
    /**
     * 뷰 객체
     * @var View
     */
    protected $view;

    /**
     * 모델 객체
     * @var Model
     */
    protected $model;

    /**
     * 언어팩 객체
     * @deprecated
     * @var Language
     */
    protected $lang;

    /**
     * 옵티마이져 객체
     * @var Optimizer
     */
    protected $optimizer;


    /**
     * 생성자
     * @param Model $Model
     * @param View $View
     * @param Language $Lang
     * @param Optimizer $Optimizer
     */
    final public function __construct($Model, $View, $Lang, $Optimizer)
    {
        $this->model        = $Model;
        $this->view         = $View;
        $this->lang         = $Lang;
        $this->optimizer    = $Optimizer;

        $this->initialize();
    }

    /**
     * 옵티마이져 객체 반환
     * @return Optimizer
     */
    final public function getOptimizerObject()
    {
        return $this->optimizer;
    }

    /**
     * 모델 객체 반환
     * @return Model
     */
    final public function getModelObject()
    {
        return $this->model;
    }

    /**
     * 뷰객체 반환
     * @return View
     */
    final public function getViewObject()
    {
        return $this->view;
    }

    /**
     * 언어팩객체 반환
     * @deprecated
     * @return Language
     */
    final public function getLangObject()
    {
        return $this->lang;
    }

    /**
     * 초기화
     * Construct 를 재정의 하지 못하도록 하는 대신, 활용 할 수 있는 초기화 메소드
     */
    public function initialize(){}

    /**
     * 기본 실행 메소드
     * 컨트롤러의 method 가 지정되어 있지않은 경우 기본으로 호출됩니다.
     */
    public function index(){}

    /**
     * 자식 클래스에서 override 해서 사용할 수 있습니다.
     * 컨트롤러의 호출된 메소드가 실행되기 전 해야할 일을 정의합니다.
     */
    public function afterInit(){}

    /**
     * 자식 클래스에서 override 해서 사용할 수 있습니다.
     * 컨트롤러의 호출된 메소드가 실행된 후 해야할 일을 정의합니다.
     */
    public function afterRun(){}
}

/**
 * --------------------------------------------
 * 예외발생 최상위 클래스
 * --------------------------------------------
 */
abstract class ExceptionCatcher
{
    /**
     * 예외 발생 타입
     */
    private $sType;

    /**
     * 예외 메세지
     */
    private $sMsg;

    /**
     * 예외 코드
     */
    private $sCode;

    /**
     * 기타 파라미터 정보
     */
    private $aParam;

    /**
     * 생성자
     *
     * @param string $sType
     * @param string $sMsg
     * @param string $sCode
     * @param array $aParam
     */
    public function __construct($sType, $sMsg=null, $sCode=0, $aParam=array())
    {
        $this->sType = $sType;
        $this->sMsg = $sMsg;
        $this->sCode = $sCode;
        $this->aParam = $aParam;
    }

    /**
     * 예외 출력
     */
    public function display() {}

    /**
     * 예외발생 타입 반환
     *
     * @return string
     */
    public function getType()
    {
        return $this->sType;
    }

    /**
     * 예외 메세지 반환
     *
     * @return string
     */
    public function getMessage()
    {
        return $this->sMsg;
    }

    /**
     * 예외 코드 반환
     *
     * @return string
     */
    public function getCode()
    {
        return $this->sCode;
    }

    /**
     * 기타 파라미터 반환
     *
     * @return array
     */
    public function getParam()
    {
        return $this->aParam;
    }
}
